<template>
  <view class="c-page" :class="ggclass" :style="[styles]">
    <c-loading-page
      v-if="pagesStatus == 0"
      :value="pagesStatus == 0"
    ></c-loading-page>
    <slot v-else-if="pagesStatus == 1" v-bind="list"></slot>
    <view class="empty-wrap" v-if="pagesStatus == 2">
      <image :src="imgFilter(emptySrc)" mode="widthFix"></image>
      <view>{{ emptyText }}</view>
    </view>
    <c-pull-up-loading :type="pullType"></c-pull-up-loading>
  </view>
</template>

<script setup lang="ts">
import { imgFilter } from "../ways/filter";
import {
  computed,
  defineProps,
  getCurrentInstance,
  onMounted,
  reactive,
  toRefs,
} from "vue";
const { proxy } = getCurrentInstance() as any;
const props = defineProps({
  emptyText: {
    // 说明文字
    type: String,
    default: "这里空空如也...",
  },
  ggclass: {
    type: String,
    default: "",
  },
  emptySrc: {
    // 图片地址
    type: String,
    default: "/static/img/empty.png",
  },
  width: {
    type: String,
    default: "",
  },
  height: {
    type: String,
    default: "",
  },
  minHeight: {
    type: String,
    default: "",
  },
  minWidth: {
    type: String,
    default: "",
  },
  api: {
    type: String,
    default: "",
  },
  params: {
    type: Object,
    default: () => {
      return {};
    },
  },
  pageSize: {
    type: [String, Number],
    default: 10,
  },
  padding: {
    type: String,
    default: "",
  },
});
let queryParams = {
  pageIndex: 1,
  pageSize: props.pageSize,
};

const state: any = reactive({
  //将公共数据提取到这里
  result: {},
  list: [],
  queryParams,
  num: 0,
  totalCount: 999,
  mixinApi: "",
  paramss: {},
  pullType: 0,
  pagesStatus: 1,
});
const { pagesStatus, pullType, list } = toRefs(state);

const styles = computed(() => {
  let params = {
    width: proxy.$rpxunit(props.width),
    height: proxy.$rpxunit(props.height),
    minWidth: proxy.$rpxunit(props.minWidth),
    minHeight: proxy.$rpxunit(props.minHeight),
    padding: props.padding
      .split(" ")
      .map((v) => proxy.$rpxunit(v))
      .join(" "),
  };
  return params;
});

onMounted(() => {
  if (props.api) {
    init(props.api, {
      ...props.params,
    });
  }
});

const init = async (api: string, params: any) => {
  let apis = api;
  // state.pagesStatus = 0
  if (typeof api !== "string" || !api) {
    apis = state.mixinApi;
  }
  if (typeof api === "object") {
    params = api;
  }
  state.num = 0;
  state.totalCount = 999;
  state.queryParams.pageIndex = state.num + 1;
  let res = await state.getList(apis, params);
  if (state.list.length) {
    state.pagesStatus = 1;
  } else {
    state.pagesStatus = 2;
  }
  return res;
};
const getList = async (api: string, params: any) => {
  state.pullType = 1;
  state.queryParams.pageIndex = state.num + 1;
  state.mixinApi = api || state.mixinApi;
  state.paramss = Object.assign(state.queryParams, state.params, params);
  let { result } = await state.$http.get(state.mixinApi, state.paramss, false);
  state.pullType = 0;
  state.result = result || {};
  if (state.num) {
    state.list.push(...state.result.items);
  } else {
    state.list = state.result.items || [];
  }
  state.totalCount = state.result.totalCount;
  if (!state.totalCount) state.pagesStatus = 2;
};
const reachBottom = () => {
  state.num++;
  state.queryParams.pageIndex = state.num + 1;
  if (!state.list) return;
  if (state.list.length >= state.totalCount) return (state.pullType = 2);
  state.getList(state.api, state.paramss);
};
const pullDownRefresh = async (api: string, params: any = {}) => {
  await state.init(api, params);
  setTimeout(function () {
    uni.stopPullDownRefresh();
  }, 1000);
};
defineExpose({
  init,
  getList,
  reachBottom,
  pullDownRefresh,
});
</script>

<style lang="scss" scoped>
.c-page {
  width: 100%;
  height: 100%;
  flex: 1;
  position: relative;
}

.empty-wrap {
  width: 100%;
  padding-top: 120rpx;
  box-sizing: border-box;

  image {
    width: 350rpx;
    height: 290rpx;
    margin-left: 50%;
    transform: translateX(-50%);
  }

  view {
    text-align: center;
    font-size: 26rpx;
    letter-spacing: 1rpx;
    color: #a1adbd;
    margin-top: 5rpx;
  }
}
</style>